package com.hcy.controller;

import com.hcy.model.RegisterUserDTO;
import com.hcy.rabbitbasicmodel.dto.MyPage;
import com.hcy.rabbitbasicmodel.enums.Clients;
import com.hcy.rabbitbasicmodel.model.ResponseData;
import com.hcy.rabbitbasicmodel.model.ReturnResult;
import com.hcy.rabbitbasicmodel.model.TokenService;
import com.hcy.rabbitbasicmodel.signl.Add;
import com.hcy.rabbitbasicutils.utils.MyHttpUtils;
import com.hcy.userclient.client.UserAuthClient;
import com.hcy.userclient.client.UserInfoClient;
import com.hcy.usermodel.dto.request.UserAuthRequestDTO;
import com.hcy.usermodel.dto.response.UserAuthsResponseDTO;
import com.hcy.utils.CheckTokenAccess;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.config.authentication.PasswordEncoderParser;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordAccessTokenProvider;
import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;

@RestController
public class LoginController {
    private static final Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Value("${security.oauth2.client.access-token-uri}")
    private String accessTokenUri;
    @Value("${security.oauth2.client.client-id}")
    private String clientId;
    @Value("${security.oauth2.client.client-secret}")
    private String clientSecret;

    @Autowired
    MyHttpUtils myHttpUtils;
    @Autowired
    CheckTokenAccess checkTokenAccess;
    @Autowired
    UserAuthClient userAuthClient;
    @Autowired
    PasswordEncoder passwordEncoder;

    @PostMapping("/login")
    public ReturnResult login(@RequestBody UserAuthRequestDTO user) {
        logger.info("login start param -> {}", ToStringBuilder.reflectionToString(user));
        //OAuth2AccessToken
        if (StringUtils.isEmpty(user.getUsername()) || StringUtils.isEmpty(user.getPassword())) {
            return ReturnResult.fail("用户名和密码不能为空");
        }
        String username = user.getUsername();
        String password = user.getPassword();

        /**
         * @Author huchenying
         * @Description  更改乘客端登录逻辑，所有人密码都是 123456,如果该手机号没有注册就自动注册一个用户，然后登录
         * @Date 2022/5/19 18:10
         **/
        // 查询是否有此用户
        UserAuthRequestDTO authRequestDTO = new UserAuthRequestDTO();
        authRequestDTO.setPageNO(1);
        authRequestDTO.setPageSize(1);
        authRequestDTO.setUsername(username);
        authRequestDTO.setBusinessCode(Clients.CUSTOMER.getName());
        ResponseData<MyPage<UserAuthsResponseDTO>> userList = userAuthClient.getUserList(authRequestDTO);
        if(userList.getCode().noSuccess()){
            return ReturnResult.fail("系统繁忙");
        }
        // 如果没有该用户就注册
        if(userList.getData() == null || CollectionUtils.isEmpty(userList.getData().getRecords())){
            UserAuthRequestDTO userAuthRequestDTO = new UserAuthRequestDTO();
            userAuthRequestDTO.setUsername(username);
            userAuthRequestDTO.setBusinessCode(Clients.CUSTOMER.getName());
            userAuthRequestDTO.setNickname("乘客");
            userAuthRequestDTO.setPassword(passwordEncoder.encode("123456"));
            ResponseData<UserAuthsResponseDTO> responseData = userAuthClient.insertOrUpdateUser(userAuthRequestDTO);
            if(responseData.getCode().noSuccess()){
                return ReturnResult.fail("系统繁忙");
            }
        }
        // 创建 ResourceOwnerPasswordResourceDetails 对象
        ResourceOwnerPasswordResourceDetails resourceDetails = new ResourceOwnerPasswordResourceDetails();
        resourceDetails.setAccessTokenUri(accessTokenUri);
        resourceDetails.setClientId(clientId);
        resourceDetails.setClientSecret(clientSecret);
        //处理用户名，携带更多信息 导致refresh_token 出现问题 bug
        username = username + "+" + "customer";
        resourceDetails.setUsername(username);
        resourceDetails.setPassword(password);
        // 创建 OAuth2RestTemplate 对象
        OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails);

        restTemplate.setAccessTokenProvider(new ResourceOwnerPasswordAccessTokenProvider());
        try {
            OAuth2AccessToken accessToken = restTemplate.getAccessToken();
            return ReturnResult.success("认证成功！").setData(accessToken);
        } catch (Exception e) {
            return ReturnResult.fail("验证码错误！");
        }
    }

    @PostMapping("/refresh_token")
    public ReturnResult refreshToken(@RequestBody TokenService tokenService) {
        logger.info("refresh_token start param -> {}", ToStringBuilder.reflectionToString(tokenService));
        try {
            MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
            MultiValueMap<String, String> header = new LinkedMultiValueMap<>();
            map.add("grant_type", "refresh_token");
            map.add("refresh_token", tokenService.getRefreshToken());
            map.add("client_id", clientId);
            map.add("client_secret", clientSecret);
            header.add("business", "driver");
            ReturnResult returnResult = myHttpUtils.sendPostRequest(accessTokenUri, map, header);
            if (returnResult.getCode() == 200) {
                return returnResult;
            } else {
                return ReturnResult.fail("刷新token失败");
            }
        } catch (Exception e) {
            return ReturnResult.fail("会话已过期请重新登录！");
        }
    }

    @PostMapping("/check_token")
    public ReturnResult checkToken(@RequestBody TokenService tokenService) {
        logger.info("checkToken start param -> {}", ToStringBuilder.reflectionToString(tokenService));
        HashMap<String, String> stringStringHashMap = checkTokenAccess.checkToken(tokenService.getToken());
        if (stringStringHashMap == null) {
            return ReturnResult.fail("会话已过期请重新登录！");
        } else {
            return ReturnResult.success("有效token").setData(stringStringHashMap);
        }
    }

    /**
     * @Author huchenying
     * @Description  注册
     * @Date 2022/5/18 23:07
     **/
    @PostMapping("/register")
    public ReturnResult register(@Validated(Add.class) @RequestBody RegisterUserDTO registerUserDTO){
        logger.info("register start param -> {}", ToStringBuilder.reflectionToString(registerUserDTO));
        UserAuthRequestDTO userAuthRequestDTO = new UserAuthRequestDTO();
        BeanUtils.copyProperties(registerUserDTO,userAuthRequestDTO);
        // 创建用户
        userAuthRequestDTO.setBusinessCode(Clients.CUSTOMER.getName());
        userAuthRequestDTO.setNickname("乘客");

        userAuthRequestDTO.setPassword(passwordEncoder.encode(registerUserDTO.getPassword()));
        ResponseData<UserAuthsResponseDTO> responseData = userAuthClient.insertOrUpdateUser(userAuthRequestDTO);
        if(responseData.getCode().noSuccess()){
            return ReturnResult.fail("系统繁忙");
        }
        // 填充用户信息（放到上个接口凑乎一下，初始化乘客信息）

        String username = registerUserDTO.getUsername();
        String password = registerUserDTO.getPassword();
        // 创建 ResourceOwnerPasswordResourceDetails 对象
        ResourceOwnerPasswordResourceDetails resourceDetails = new ResourceOwnerPasswordResourceDetails();
        resourceDetails.setAccessTokenUri(accessTokenUri);
        resourceDetails.setClientId(clientId);
        resourceDetails.setClientSecret(clientSecret);
        //处理用户名，携带更多信息 导致refresh_token 出现问题 bug
        username = username + "+" + "customer";
        resourceDetails.setUsername(username);
        resourceDetails.setPassword(password);
        // 创建 OAuth2RestTemplate 对象
        OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails);

        restTemplate.setAccessTokenProvider(new ResourceOwnerPasswordAccessTokenProvider());
        try {
            OAuth2AccessToken accessToken = restTemplate.getAccessToken();
            return ReturnResult.success("注册成功！").setData(accessToken);
        } catch (Exception e) {
            return ReturnResult.fail("用户名或密码错误！");
        }
    }
}
